<html>
 <head>
  <meta charset="UTF-8">
 </head>
 <body>
  <h1 data-lake-id="VCkGv" id="VCkGv"><span data-lake-id="ue9e878f6" id="ue9e878f6">典型回答</span></h1>
  <p data-lake-id="u0ec4f46a" id="u0ec4f46a"><span data-lake-id="ub8802190" id="ub8802190">Java的整个集合框架中，主要分为List，Set，Queue，Stack，Map等五种数据结构。其中，前四种数据结构都是单一元素的集合，而最后的Map则是以KV对的形式使用。</span></p>
  <p data-lake-id="u0bfd38d4" id="u0bfd38d4"><span data-lake-id="u8ea7878c" id="u8ea7878c">​</span><br></p>
  <p data-lake-id="u5beaea0b" id="u5beaea0b"><span data-lake-id="u1014c36c" id="u1014c36c">从继承关系上讲，List，Set，Queue都是Collection的子接口，Collection又继承了Iterable接口，说明这几种集合都是可以遍历的。</span></p>
  <p data-lake-id="u0a731703" id="u0a731703"><span data-lake-id="u4d7eea60" id="u4d7eea60">​</span><br></p>
  <p data-lake-id="ub8b767b4" id="ub8b767b4"><img src="https://cdn.nlark.com/yuque/0/2023/png/5378072/1693116712014-5a1db396-f4e1-4d57-b2fd-33ae8f0410d7.png?x-oss-process=image%2Fwatermark%2Ctype_d3F5LW1pY3JvaGVp%2Csize_38%2Ctext_SmF2YSA4IEd1IFA%3D%2Ccolor_FFFFFF%2Cshadow_50%2Ct_80%2Cg_se%2Cx_10%2Cy_10"></p>
  <p data-lake-id="ua5f5e6ec" id="ua5f5e6ec"><span data-lake-id="u06cfb265" id="u06cfb265">​</span><br></p>
  <p data-lake-id="u22980071" id="u22980071"><span data-lake-id="u5d6215f3" id="u5d6215f3">从功能上讲，List代表一个容器，可以是先进先出，也可以是先进后出。而Set相对于List来说，是无序的，同时也是一个去重的列表，既然会去重，就一定会通过equals，compareTo，hashCode等方法进行比较。Map则是KV的映射，也会涉及到Key值的查询等能力。</span></p>
  <p data-lake-id="u7f8ea827" id="u7f8ea827"><span data-lake-id="u64d02148" id="u64d02148">​</span><br></p>
  <p data-lake-id="u891015e5" id="u891015e5"><span data-lake-id="u022f30e4" id="u022f30e4">从实现上讲，List可以有链表实现或者数组实现，两者各有优劣，链表增删快，数组查询快。Queue则可以分为优先队列，双端队列等等。Map则可以分为普通的HashMap和可以排序的TreeMap等等。</span></p>
  <h1 data-lake-id="yFTqQ" id="yFTqQ"><span data-lake-id="u3f7ae653" id="u3f7ae653">知识扩展</span></h1>
  <h2 data-lake-id="rVhpv" id="rVhpv"><strong><span data-lake-id="u4ee7c8e4" id="u4ee7c8e4" class="lake-fontsize-24" style="color: rgb(38, 38, 38)">Collection和Collections有什么区别？</span></strong></h2>
  <ol list="u53934441">
   <li fid="u4c15d474" data-lake-id="ue2cb7e7e" id="ue2cb7e7e"><strong><span data-lake-id="ueb29805b" id="ueb29805b">Collection 是一个集合接口：</span></strong><span data-lake-id="ue0db4a8f" id="ue0db4a8f">它提供了对集合对象进行基本操作的通用接口方法。Collection接口在Java 类库中有很多具体的实现。是list，set等的父接口。</span></li>
   <li fid="u4c15d474" data-lake-id="u1d322cb7" id="u1d322cb7"><strong><span data-lake-id="u4d78c536" id="u4d78c536">Collections 是一个包装类：</span></strong><span data-lake-id="u8e12e192" id="u8e12e192">它包含有各种有关集合操作的静态多态方法。此类不能实例化，就像一个工具类，服务于Java的Collection框架。</span></li>
  </ol>
  <p data-lake-id="ufe6ca7e3" id="ufe6ca7e3"><span data-lake-id="u0aa7e419" id="u0aa7e419">日常开发中，不仅要了解Java中的Collection及其子类的用法，还要了解Collections用法。可以提升很多处理集合类的效率。</span></p>
  <h2 data-lake-id="U75vQ" id="U75vQ"><strong><span data-lake-id="u985ceff7" id="u985ceff7" class="lake-fontsize-24" style="color: rgb(38, 38, 38)">Java中的Collection如何遍历迭代？</span></strong></h2>
  <ol list="ub388d872">
   <li fid="u3f273aff" data-lake-id="u333bec52" id="u333bec52"><strong><span data-lake-id="u1bc656e8" id="u1bc656e8">传统的for循环遍历，基于计数器的：</span></strong><span data-lake-id="u18fb7372" id="u18fb7372">遍历者自己在集合外部维护一个计数器，然后依次读取每一个位置的元素，当读取到最后一个元素后，停止。主要就是需要按元素的位置来读取元素。</span></li>
   <li fid="u3f273aff" data-lake-id="u4e563136" id="u4e563136"><strong><span data-lake-id="u96f1547e" id="u96f1547e">迭代器遍历，Iterator：</span></strong><span data-lake-id="u371294c1" id="u371294c1">每一个具体实现的数据集合，一般都需要提供相应的Iterator。相比于传统for循环，Iterator取缔了显式的遍历计数器。所以基于顺序存储集合的Iterator可以直接按位置访问数据。而基于链式存储集合的Iterator，正常的实现，都是需要保存当前遍历的位置。然后根据当前位置来向前或者向后移动指针。</span></li>
   <li fid="u3f273aff" data-lake-id="u0e4d84d9" id="u0e4d84d9"><strong><span data-lake-id="ud2b55f5f" id="ud2b55f5f">foreach循环遍历：</span></strong><span data-lake-id="u6973a116" id="u6973a116">根据反编译的字节码可以发现，foreach内部也是采用了Iterator的方式实现，只不过Java编译器帮我们生成了这些代码。</span></li>
   <li fid="u3f273aff" data-lake-id="u7a91123a" id="u7a91123a"><strong><span data-lake-id="ud5a11ccb" id="ud5a11ccb">迭代器遍历：Enumeration：</span></strong><span data-lake-id="ua1988aae" id="ua1988aae">Enumeration 接口是Iterator迭代器的“古老版本”，从JDK 1.0开始，Enumeration接口就已经存在了（Iterator从JDK 1.2才出现）</span></li>
   <li fid="u3f273aff" data-lake-id="u8d571aed" id="u8d571aed"><strong><span data-lake-id="u0bf2cef7" id="u0bf2cef7">Stream：</span></strong><span data-lake-id="uc54dc1a4" id="uc54dc1a4">JDK 1.8中新增Stream，使用一种类似用 SQL 语句从数据库查询数据的直观方式来提供一种对 Java 集合运算和表达的高阶抽象。Stream API可以极大提高Java程序员的生产力，让程序员写出高效率、干净、简洁的代码。</span></li>
  </ol>
  <h2 data-lake-id="ncF0B" id="ncF0B"><span data-lake-id="u331721f3" id="u331721f3">Iterable和Iterator如何使用?</span></h2>
  <p data-lake-id="u00a248f7" id="u00a248f7"><span data-lake-id="u9218ab3f" id="u9218ab3f">Iterator和Iterable是两个接口，前者代表的是迭代的方式，如next和hasNext方法就是需要在该接口中实现。后者代表的是是否可以迭代，如果可以迭代，会返回Iterator接口，即返回迭代方式</span></p>
  <p data-lake-id="uf2883b70" id="uf2883b70"><span data-lake-id="u9b08882a" id="u9b08882a">​</span><br></p>
  <p data-lake-id="u76af1cff" id="u76af1cff"><span data-lake-id="u0d9d732b" id="u0d9d732b">常见的使用方式一般是集合实现Iterable表明该集合可以遍历，同时选择Iterator或者自定义一个Iterator的实现类去选择遍历方式，如：</span></p>
  <pre lang="java"><code>
class AbstractList&lt;E&gt; implements Iterable&lt;E&gt; {
    public Iterator&lt;E&gt; iterator() {
        return new Itr();
    }

    private class Itr implements Iterator&lt;E&gt; {}
}
</code></pre>
  <h3 data-lake-id="fD9w5" id="fD9w5"><br></h3>
  <h3 data-lake-id="kmiLY" id="kmiLY"><span data-lake-id="u9b711ec3" id="u9b711ec3">为什么不把Iterable和Iterator合成一个使用</span></h3>
  <ol list="ub4bb0172">
   <li fid="u622b87d3" data-lake-id="ub8093b61" id="ub8093b61"><span data-lake-id="u56259591" id="u56259591">通过Javadoc文档我们可以发现，Iterable和Iterator并不是同时出现的，Iterator于1.2就出现了，目的是为了代替Enumeration，而Iterable则是1.5才出现的</span></li>
   <li fid="u622b87d3" data-lake-id="u03f7f792" id="u03f7f792"><span data-lake-id="u716816b6" id="u716816b6">将是否可以迭代和迭代方式抽出来，更符合单一职责原则，如果抽出来，迭代方式就可以被多个可迭代的集合复用，更符合面向对象的特点。</span></li>
  </ol>
 </body>
</html>